#!/bin/bash

# 颜色定义
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[0;33m'
BLUE='\033[0;34m'
CYAN='\033[0;36m'
NC='\033[0m' # No Color

# 全局变量
CLEAN_HOSTNAME=""
CLEAN_USERNAME=""
CLEAN_BASE_DIR=""
NETWORK_NAME=""
NETWORK_SECRET=""
INSTALL_MODE=""

# 错误处理
die() {
    echo -e "${RED}[错误] $1${NC}" >&2
    read -p "按回车键退出..."
    exit 1
}

# 日志函数
log() {
    echo -e "${BLUE}[信息] $1${NC}"
}

success() {
    echo -e "${GREEN}[成功] $1${NC}"
}

warn() {
    echo -e "${YELLOW}[警告] $1${NC}"
}

# 清理字符串 - 移除所有颜色代码和特殊字符
clean_string() {
    echo "$1" | sed -E 's/\x1B\[[0-9;]*[mK]//g' | sed 's/^\[[^]]*\]//g' | tr -d '\n\r' | sed 's/^[[:space:]]*//;s/[[:space:]]*$//'
}

# 选择安装模式
select_install_mode() {
    echo -e "${CYAN}请选择安装模式:${NC}"
    echo -e "   ##请先到EasyTier官网注册:  https://easytier.cn/web#/auth/register  "
    echo
    echo -e "  1) 创建新网络 (可到官网后台为不同机器，建立同样的网络名称和密码组网-去中心组网)"
    echo -e "  2) 加入现有网络（加入已经创建的网络-无去中心化，创建网络机器为中心，若断开其它所有都断开）"
    echo
    
    local choice
    read -p "请输入选择 (1/2): " choice
    
    case $choice in
        1)
            INSTALL_MODE="new"
            log "选择模式: 创建新网络"
            ;;
        2)
            INSTALL_MODE="join"
            log "选择模式: 加入现有网络"
            ;;
        *)
            warn "无效选择，使用默认模式: 新安装"
            INSTALL_MODE="new"
            ;;
    esac
}

# 获取网络信息
get_network_info() {
    if [ "$INSTALL_MODE" = "join" ]; then
        echo
        log "请输入要加入的网络信息"
        
        local attempts=0
        local max_attempts=3
        
        while [ $attempts -lt $max_attempts ]; do
            read -p "网络名称 (networkname): " NETWORK_NAME
            NETWORK_NAME=$(clean_string "$NETWORK_NAME")
            NETWORK_NAME=$(echo "$NETWORK_NAME" | tr -d ' \t' | sed 's/[^a-zA-Z0-9._-]//g')
            
            if [ -z "$NETWORK_NAME" ]; then
                warn "网络名称不能为空"
                ((attempts++))
                continue
            fi
            
            read -p "网络密钥 (networksecret): " NETWORK_SECRET
            NETWORK_SECRET=$(clean_string "$NETWORK_SECRET")
            NETWORK_SECRET=$(echo "$NETWORK_SECRET" | tr -d ' \t' | sed 's/[^a-zA-Z0-9._-]//g')
            
            if [ -z "$NETWORK_SECRET" ]; then
                warn "网络密钥不能为空"
                ((attempts++))
                continue
            fi
            
            echo
            echo -e "${CYAN}网络信息确认:${NC}"
            echo -e "  - 网络名称: ${GREEN}$NETWORK_NAME${NC}"
            echo -e "  - 网络密钥: ${GREEN}******${NC}"
            
            read -p "确认网络信息是否正确？(y/n) [y]: " confirm
            confirm=${confirm:-y}
            
            if [[ "$confirm" =~ ^[Yy]$ ]]; then
                break
            else
                ((attempts++))
                continue
            fi
        done
        
        if [ $attempts -ge $max_attempts ]; then
            die "输入尝试次数过多"
        fi
    fi
}

# 获取主机名
get_hostname() {
    local hostname
    
    # 尝试获取系统主机名
    if command -v hostname &>/dev/null; then
        hostname=$(hostname 2>/dev/null)
        hostname=$(clean_string "$hostname")
    fi
    
    # 如果获取不到或为空，生成随机主机名
    if [ -z "$hostname" ]; then
        local random_suffix=$(head /dev/urandom | tr -dc '0-9' | head -c 3 2>/dev/null || echo "001")
        hostname="easytier${random_suffix}"
        warn "无法获取系统主机名，使用: $hostname"
    else
        success "使用系统主机名: $hostname"
    fi
    
    CLEAN_HOSTNAME="$hostname"
}

# 获取EasyTier用户名
get_easytier_username() {
    local username
    local attempts=0
    local max_attempts=3
    
    while [ $attempts -lt $max_attempts ]; do
        echo
        echo "请先到EasyTier官网注册:https://easytier.cn/web#/auth/register"
        read -p "请输入您的EasyTier用户名: " username
        
        if [ -z "$username" ]; then
            warn "用户名不能为空"
            ((attempts++))
            continue
        fi
        
        username=$(clean_string "$username")
        username=$(echo "$username" | tr -d ' \t' | sed 's/[^a-zA-Z0-9._-]//g')
        
        if [ -z "$username" ]; then
            warn "用户名包含无效字符"
            ((attempts++))
            continue
        fi
        
        echo
        read -p "确认使用用户名 '${username}'？(y/n) [y]: " confirm
        confirm=${confirm:-y}
        
        if [[ "$confirm" =~ ^[Yy]$ ]]; then
            break
        else
            ((attempts++))
            continue
        fi
    done
    
    if [ $attempts -ge $max_attempts ]; then
        die "输入尝试次数过多"
    fi
    
    CLEAN_USERNAME="$username"
}

# 获取Docker目录
get_docker_dir() {
    local dir=""
    
    if [ -d "/volume1" ]; then
        dir=$(find /volume* -maxdepth 1 -type d -name "docker" 2>/dev/null | head -n1)
        [ -z "$dir" ] && dir="/volume1/docker"
        log "检测到群辉DSM系统"
    elif [ -d "/vol1" ]; then
        dir=$(find /vol* -maxdepth 2 -type d -name "docker" 2>/dev/null | head -n1)
        [ -z "$dir" ] && dir="/vol1/docker"
        log "检测到FNOS系统"
    else
        if [ -w "/opt" ]; then
            dir="/opt/docker"
        else
            dir="$HOME/docker"
        fi
        log "检测到通用Linux系统"
    fi
    
    dir=$(clean_string "$dir")
    dir=$(echo "$dir" | sed 's/\/\//\//g')
    
    mkdir -p "$dir" || die "无法创建目录 $dir"
    
    CLEAN_BASE_DIR="$dir"
}

# 检查Docker环境
check_docker() {
    log "检查Docker环境..."
    if ! command -v docker &>/dev/null; then
        die "Docker未安装，请先安装Docker"
    fi
    
    if ! docker info &>/dev/null; then
        die "Docker服务未运行，请启动Docker服务"
    fi
    
    success "Docker环境检查通过"
}

# 清理旧容器
cleanup_old_container() {
    if docker ps -aq --filter "name=easytier" | grep -q .; then
        log "发现已存在的easytier容器，正在清理..."
        docker stop easytier >/dev/null 2>&1 || true
        docker rm easytier >/dev/null 2>&1 || true
        success "旧容器清理完成"
    fi
}

# 检查TUN设备
check_tun_device() {
    log "检查TUN设备..."
    if [ ! -c "/dev/net/tun" ]; then
        warn "TUN设备 /dev/net/tun 不存在，尝试创建..."
        
        sudo mkdir -p /dev/net 2>/dev/null || warn "无法创建/dev/net目录，继续..."
        
        if ! sudo mknod /dev/net/tun c 10 200 2>/dev/null; then
            warn "无法创建TUN设备，容器启动可能会失败"
        else
            sudo chmod 0666 /dev/net/tun 2>/dev/null || true
            success "TUN设备创建完成"
        fi
    else
        success "TUN设备检查通过"
    fi
}

# 构建Docker命令
build_docker_command() {
    local command_args=""
    
    if [ "$INSTALL_MODE" = "new" ]; then
        # 新安装模式
        command_args="-w $CLEAN_USERNAME"
    else
        # 加入网络模式
        command_args="-d --network-name $NETWORK_NAME --network-secret $NETWORK_SECRET -p tcp://public.easytier.cn:11010"
    fi
    
    # 返回纯净的命令，不包含颜色代码
    echo "$command_args"
}

# 安装EasyTier
install_easytier() {
    echo
    log "开始安装EasyTier..."
    echo -e "${CYAN}配置信息:${NC}"
    echo -e "  - 安装模式: ${GREEN}$([ "$INSTALL_MODE" = "new" ] && echo "新安装创建网络" || echo "加入现有网络")${NC}"
    echo -e "  - 主机名: ${GREEN}$CLEAN_HOSTNAME${NC}"
    echo -e "  - 用户名: ${GREEN}$CLEAN_USERNAME${NC}"
    
    if [ "$INSTALL_MODE" = "join" ]; then
        echo -e "  - 网络名称: ${GREEN}$NETWORK_NAME${NC}"
        echo -e "  - 网络密钥: ${GREEN}******${NC}"
    fi
    
    echo -e "  - 数据目录: ${GREEN}$CLEAN_BASE_DIR/easytier${NC}"
    
    local data_dir="$CLEAN_BASE_DIR/easytier"
    local docker_command=$(build_docker_command)
    
    # 显示使用的命令（仅用于信息显示）
    if [ "$INSTALL_MODE" = "new" ]; then
        log "使用新安装模式命令: -w <用户名>"
    else
        log "使用加入网络模式命令: -d --network-name <网络名> --network-secret <密钥> -p tcp://public.easytier.cn:11010"
    fi
    
    mkdir -p "$data_dir" || die "无法创建EasyTier数据目录: $data_dir"
    chmod 755 "$data_dir" 2>/dev/null || warn "无法设置目录权限"
    
    check_tun_device
    cleanup_old_container
    
    log "正在拉取EasyTier镜像..."
    if ! docker pull easytier/easytier:latest; then
        warn "镜像拉取失败，尝试使用本地镜像启动..."
    fi
    
    log "正在启动EasyTier容器..."
    
    # 显示实际执行的命令
    echo -e "${YELLOW}执行命令: docker run ... $docker_command${NC}"
    
    if docker run -d \
        --name easytier \
        --hostname "$CLEAN_HOSTNAME" \
        --restart=always \
        --network=host \
        --cap-add=NET_ADMIN \
        --cap-add=NET_RAW \
        -e TZ=Asia/Shanghai \
        --device /dev/net/tun:/dev/net/tun \
        -v "${data_dir}:/root" \
        -v "/etc/machine-id:/etc/machine-id:ro" \
        easytier/easytier:latest \
        $docker_command; then
        
        success "EasyTier容器启动成功"
    else
        docker logs easytier 2>&1 | head -n 20 || true
        die "启动EasyTier容器失败"
    fi
    
    log "验证容器状态..."
    sleep 5
    if docker ps --filter "name=easytier" --format "{{.Status}}" | grep -q "Up"; then
        success "EasyTier容器运行正常"
    else
        warn "容器状态异常，查看日志..."
        docker logs easytier 2>&1 | head -n 30
        die "容器启动后异常退出"
    fi
    
    echo
    echo -e "${GREEN}========== EasyTier 安装成功 ==========${NC}"
    echo -e "${CYAN}容器名称:${NC} easytier"
    echo -e "${CYAN}主机名称:${NC} $CLEAN_HOSTNAME"
    echo -e "${CYAN}EasyTier用户:${NC} $CLEAN_USERNAME"
    if [ "$INSTALL_MODE" = "join" ]; then
        echo -e "${CYAN}加入网络:${NC} $NETWORK_NAME"
    else
        echo -e "${CYAN}安装模式:${NC} 新网络创建"
    fi
    echo -e "${CYAN}数据目录:${NC} $data_dir"
    echo -e "${CYAN}网络模式:${NC} host"
    echo -e "${CYAN}容器状态:${NC} $(docker ps --filter "name=easytier" --format "{{.Status}}")"
    echo -e "${CYAN}查看日志:${NC} docker logs -f easytier"
    echo -e "${CYAN}停止服务:${NC} docker stop easytier"
    echo -e "${CYAN}重启服务:${NC} docker restart easytier"
    echo -e "${GREEN}======================================${NC}"
}

# 主流程
main() {
    echo -e "${BLUE}=== EasyTier 自动化安装脚本 ===${NC}"
    echo
    
    check_docker
    
    # 选择安装模式
    select_install_mode
    
    # 获取网络信息（如果是加入网络模式）
    get_network_info
    
    get_hostname
    echo -e "${GREEN}[结果] 主机名: $CLEAN_HOSTNAME${NC}"
    echo
    
    get_easytier_username
    echo -e "${GREEN}[结果] 用户名: $CLEAN_USERNAME${NC}"
    echo
    
    get_docker_dir
    echo -e "${GREEN}[结果] Docker目录: $CLEAN_BASE_DIR${NC}"
    echo
    
    install_easytier
    
    echo
    read -p "按回车键退出..."
}

if [ "${BASH_SOURCE[0]}" = "$0" ]; then
    main "$@"
fi